package com.corner.ui.adapter;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.net.Uri;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.corner.R;
import com.corner.app.ConsTants;
import com.corner.model.cornerservice.domain.User;

import com.corner.model.db.DBConstans;
import com.corner.model.db.Session;
import com.corner.presenter.imp.ChatAudioPresenter;
import com.corner.presenter.imp.ChatCommentPresenter;
import com.corner.ui.activity.ChannelActivity;
import com.corner.ui.activity.ChatActivity;
import com.corner.ui.activity.ProfileActivity;
import com.corner.ui.activity.ShowImageActivity;
import com.corner.ui.activity.ShowSingleInfo;
import com.corner.ui.base.BaseHolder;
import com.corner.ui.view.IChatCommentView;
import com.corner.utils.AudioPlayer;
import com.corner.utils.DateFormatUtil;
import com.corner.utils.view.CustomFont;
import com.corner.utils.view.FindView;
import com.corner.utils.view.InjectViewUtils;
import com.facebook.drawee.view.SimpleDraweeView;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * Created by Administrator on 2015/5/8.
 */
public class ChatMessageAdapter extends BaseAdapter implements View.OnClickListener, View.OnLongClickListener {

    /**
     * 显示时间的间隔为1分钟
     */
    public static final int MAX_DURATION = 1 * 60 * 1000;
    public static final int TEXT_LEFT = 0;
    public static final int TEXT_RIGHT = 1;
    public static final int PIC_LEFT = 2;
    public static final int PIC_RIGHT = 3;
    public static final int PIC_AUDIO_LEFT = 4;
    public static final int PIC_AUDIO_RIGHT = 5;
    public static final int COMMENT_LEFT = 6;
    public static final int COMMENT_RIGHT = 7;
    public static final String AUDIO_PATH_NAME = "audio";
    private final String selfId;
    private Context context;
    private List<Session> sessionList;
    private String selfAvaterUrl;
    private String friendAvaterUrl;
    private long lastShowTime;
    private AudioPlayer audioPlayer;

    /**
     * @param context
     * @param sessionList
     * @param selfAvaterUrl
     * @param friendAvaterUrl
     */
    public ChatMessageAdapter(Context context, List<Session> sessionList, String selfAvaterUrl, String friendAvaterUrl) {
        this.context = context;
        this.sessionList = sessionList;
        this.selfAvaterUrl = selfAvaterUrl;
        this.friendAvaterUrl = friendAvaterUrl;
        selfId = User.getCurrentUser().getObjectId().toString();
    }

    public void stopAudio() {
        if (audioPlayer != null && audioPlayer.isPlaying()) {
            audioPlayer.stop();
        }
    }

    @Override
    public int getCount() {
        return sessionList.size();
    }

    @Override
    public Object getItem(int position) {
        return sessionList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            switch (getItemViewType(position)) {
                case TEXT_RIGHT:
                    convertView = View.inflate(context, R.layout.chat_right_text, null);
                    inflateText(position, convertView, selfAvaterUrl);
                    break;
                case TEXT_LEFT:
                    convertView = View.inflate(context, R.layout.chat_left_text, null);
                    inflateText(position, convertView, friendAvaterUrl);
                    break;
                case PIC_RIGHT:
                    convertView = View.inflate(context, R.layout.chat_right_pic, null);
                    inflatePic(position, convertView, selfAvaterUrl);
                    break;
                case PIC_LEFT:
                    convertView = View.inflate(context, R.layout.chat_left_pic, null);
                    inflatePic(position, convertView, friendAvaterUrl);
                    break;
                case PIC_AUDIO_RIGHT:
                    convertView = View.inflate(context, R.layout.chat_right_pic_audio, null);
                    inflatePicAudio(position, convertView, selfAvaterUrl);
                    break;
                case PIC_AUDIO_LEFT:
                    convertView = View.inflate(context, R.layout.chat_left_pic_audio, null);
                    inflatePicAudio(position, convertView, friendAvaterUrl);
                    break;
                case COMMENT_RIGHT:
                    convertView = View.inflate(context, R.layout.chat_comment_right, null);
                    inflateComment(position, convertView, selfAvaterUrl);
                    break;
                case COMMENT_LEFT:
                    convertView = View.inflate(context, R.layout.chat_comment_left, null);
                    inflateComment(position, convertView, friendAvaterUrl);
                    break;
            }
        } else {
            switch (getItemViewType(position)) {
                case TEXT_RIGHT:
                    Text text = (Text) convertView.getTag();
                    fillText(position, selfAvaterUrl, text);
                    break;
                case TEXT_LEFT:
                    text = (Text) convertView.getTag();
                    fillText(position, friendAvaterUrl, text);
                    break;
                case PIC_RIGHT:
                    Pic pic = (Pic) convertView.getTag();
                    fillPic(position, selfAvaterUrl, pic);
                    break;
                case PIC_LEFT:
                    pic = (Pic) convertView.getTag();
                    fillPic(position, friendAvaterUrl, pic);
                    break;
                case PIC_AUDIO_RIGHT:
                    PicAudio picaudio = (PicAudio) convertView.getTag();
                    fillPicAudio(position, selfAvaterUrl, picaudio);
                    break;
                case PIC_AUDIO_LEFT:
                    picaudio = (PicAudio) convertView.getTag();
                    fillPicAudio(position, friendAvaterUrl, picaudio);
                    break;
                case COMMENT_RIGHT:
                    Comment comment = (Comment) convertView.getTag();
                    fillComment(position, selfAvaterUrl, comment);
                    break;
                case COMMENT_LEFT:
                    comment = (Comment) convertView.getTag();
                    fillComment(position, friendAvaterUrl, comment);
                    break;
            }
        }
        convertView.setTag(R.integer.view_long_click_session, sessionList.get(position));
        convertView.setOnLongClickListener(this);
        convertView.setTag(R.integer.view_click_session, true);
        convertView.setOnClickListener(this);
        return convertView;
    }

    private void inflateComment(int position, View convertView, String avaterUrl) {
        final Comment comment = new Comment();
        InjectViewUtils.injectView(comment, convertView, context);
        InjectViewUtils.injectView(comment.base, convertView, context);
        convertView.setTag(comment);
        fillComment(position, avaterUrl, comment);
    }

    private void fillComment(int position, String avaterUrl, final Comment comment) {
        Session session = sessionList.get(position);
        switch (session.getType()) {
            case DBConstans.SHARE:
                if (!session.getSessionId().equals(comment.tvCommentText.getTag())) {
                    comment.tvCommentText.setText(session.getText());
                    comment.tvCommentText.setTag(session.getSessionId());
                    comment.ivContentPic.setVisibility(View.GONE);
                    comment.requestLocation(session.getLocationId());
                    ((ViewGroup) (comment.ivContentRecommondInto.getParent())).setOnClickListener(this);
                    ((ViewGroup) (comment.ivContentRecommondInto.getParent())).setTag(session);
                }
                break;
            case DBConstans.COMMENT:
            case DBConstans.LIKE:
                if (!session.getSessionId().equals(comment.tvCommentText.getTag())) {
                    comment.tvCommentText.setText(session.getText());
                    comment.tvCommentText.setTag(session.getSessionId());
                    comment.ivContentPic.setVisibility(View.GONE);
                    comment.requestInfo(session.getInfoId());
                    comment.setSession(session);
                    ((ViewGroup) (comment.ivContentRecommondInto.getParent())).setOnClickListener(this);
                    ((ViewGroup) (comment.ivContentRecommondInto.getParent())).setTag(session);
                }
                break;
        }
        inflateBase(position, avaterUrl, comment.base, session);
    }

    private void inflatePicAudio(int position, View convertView, String avaterUrl) {
        final PicAudio pic = new PicAudio();
        InjectViewUtils.injectView(pic, convertView, context);
        InjectViewUtils.injectView(pic.base, convertView, context);
        convertView.setTag(pic);
        fillPicAudio(position, avaterUrl, pic);
    }

    private void fillPicAudio(int position, String avaterUrl, final PicAudio pic) {
        final Session session = sessionList.get(position);
        if (pic.ivPic.getTag(R.integer.pic_key_session) != null && ((Session) pic.ivPic.getTag(R.integer.pic_key_session)).getSessionId().equals(session.getSessionId())
                || pic.ivPic.getTag(R.integer.pic_key_session) == null) {
            if (!TextUtils.isEmpty(session.getPicPath()) && new File(session.getPicPath()).exists()) {
                pic.ivPic.setImageURI(Uri.fromFile(new File(session.getPicPath())));
            } else {
                if (session.getPic() != null)
                    pic.ivPic.setImageURI(Uri.parse(session.getPic()));
            }
        }
        pic.ivPic.setOnClickListener(this);
        pic.ivPic.setTag(R.integer.pic_key_session, session);
        inflateBase(position, avaterUrl, pic.base, session);
        pic.tvText.setTag(R.integer.audio_play_key_session, session);
        changeAudioDrawable(session, pic.tvText);
        pic.tvText.setText(Long.parseLong(session.getAudioDuration()) / 1000 + "'");
        pic.downAudio(session);
        pic.tvText.setOnClickListener(this);
    }

    private void inflatePic(int position, View convertView, String avaterUrl) {
        Pic pic = new Pic();
        InjectViewUtils.injectView(pic, convertView, context);
        InjectViewUtils.injectView(pic.base, convertView, context);
        convertView.setTag(pic);
        fillPic(position, avaterUrl, pic);
    }

    private void fillPic(int position, String avaterUrl, Pic pic) {
        Session session = sessionList.get(position);
        if (pic.ivPic.getTag(R.integer.pic_key_session) != null && !((Session) pic.ivPic.getTag(R.integer.pic_key_session)).getSessionId().equals(session.getSessionId())
                || pic.ivPic.getTag(R.integer.pic_key_session) == null) {
            if (!TextUtils.isEmpty(session.getPicPath()) && new File(session.getPicPath()).exists()) {
                pic.ivPic.setImageURI(Uri.fromFile(new File(session.getPicPath())));
            } else {
                if (session.getPic() != null)
                    pic.ivPic.setImageURI(Uri.parse(session.getPic()));
            }
        }
        pic.ivPic.setOnClickListener(this);
        pic.ivPic.setTag(R.integer.pic_key_session, session);
        inflateBase(position, avaterUrl, pic.base, session);
    }

    private void inflateText(int position, View convertView, String avaterUrl) {
        final Text text = new Text();
        InjectViewUtils.injectView(text, convertView, context);
        InjectViewUtils.injectView(text.base, convertView, context);

        convertView.setTag(text);
        fillText(position, avaterUrl, text);
    }

    private void fillText(int position, String avaterUrl, final Text text) {
        final Session session = sessionList.get(position);
        if (session.getType().equals(DBConstans.TEXT)) {
            text.tvText.setText(session.getText());
            text.tvText.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            text.tvText.setTag(R.integer.audio_play_key_session, null);
        } else if (session.getType().equals(DBConstans.AUDIO)) {
            text.tvText.setText(Long.parseLong(session.getAudioDuration()) / 1000 + "'");
            text.downAudio(session);
            text.tvText.setOnClickListener(this);
            text.tvText.setTag(R.integer.audio_play_key_session, session);
            changeAudioDrawable(session, text.tvText);
        }
        inflateBase(position, avaterUrl, text.base, session);
    }

    /**
     * 填充公共的信息
     *
     * @param position
     * @param avaterUrl
     * @param base
     * @param session
     */
    private void inflateBase(int position, String avaterUrl, Base base, Session session) {
        long timestamp = session.getTimestamp().getTime();
        if (position == 0 || timestamp - lastShowTime > MAX_DURATION) {
            lastShowTime = timestamp;
            base.tvSendTime.setVisibility(View.VISIBLE);
            base.tvSendTime.setText(DateFormatUtil.getTime("yyyy-MM-dd HH:mm:ss", timestamp));
        } else {
            base.tvSendTime.setVisibility(View.GONE);
        }
        base.ivAvater.setOnClickListener(this);
        base.ivAvater.setTag(R.integer.avater_session, session);
        if (avaterUrl != null)
            base.ivAvater.setImageURI(Uri.parse(avaterUrl));
        if (session.getFromUserId().equals(selfId)) {
            if (DBConstans.SENTING.equals(session.getIsSent())) {
                base.sendingBar.setVisibility(View.VISIBLE);
                base.ivFailedStatus.setVisibility(View.GONE);
            } else if (DBConstans.SENT.equals(session.getIsSent())) {
                base.sendingBar.setVisibility(View.GONE);
                base.ivFailedStatus.setVisibility(View.GONE);
            } else if (DBConstans.SENT_FAILED.equals(session.getIsSent())) {
                base.sendingBar.setVisibility(View.GONE);
                base.ivFailedStatus.setVisibility(View.VISIBLE);
                base.ivFailedStatus.setOnClickListener(this);
                base.ivFailedStatus.setTag(R.integer.send_failed_session, session);
            }
        }
    }

    /**
     * Called when a view has been clicked.
     *
     * @param v The view that was clicked.
     */
    @Override
    public void onClick(View v) {
        if (v instanceof TextView) {
            if (v.getTag(R.integer.audio_play_key_session) != null) {
                Session session = (Session) (v.getTag(R.integer.audio_play_key_session));
                if (audioPlayer != null && audioPlayer.isPlaying()) {
                    audioPlayer.stop();
                    session.isPlaying = false;
                    changeAudioDrawable(session, (TextView) v);
                    if (audioPlayer.getPath() != null && !audioPlayer.getPath().equals(session.getAudioPath())) {
                        play(session, (TextView) v, session.getAudioPath());
                    }
                } else {
                    play(session, (TextView) v, session.getAudioPath());
                }
            }
        } else if (v instanceof ImageView) {
            if (v.getTag(R.integer.pic_key_session) != null) {
                Session session = (Session) (v.getTag(R.integer.pic_key_session));
                Intent intent = new Intent(context, ShowImageActivity.class);
                if (!TextUtils.isEmpty(session.getPicPath()) && new File(session.getPicPath()).exists()) {
                    intent.putExtra(ShowImageActivity.IMAGE_PATH, session.getPicPath());
                } else {
                    intent.putExtra(ShowImageActivity.IMAGE_URL, session.getPic());
                }
                context.startActivity(intent);
            } else if (v.getTag(R.integer.send_failed_session) != null) {
                Session session = (Session) (v.getTag(R.integer.send_failed_session));
                ((ChatActivity) context).showReSentDialog(session);
            } else if (v.getTag(R.integer.avater_session) != null) {
                Session session = (Session) (v.getTag(R.integer.avater_session));
                Intent intent = new Intent(context, ProfileActivity.class);
                intent.putExtra(ProfileActivity.USER_ID, Long.parseLong(session.getFromUserId()));
                context.startActivity(intent);
            }
        } else if (v instanceof ViewGroup) {
            Object tag = v.getTag();
            if (tag != null&&tag instanceof Session) {
                Intent intent;
                Session session = (Session) tag;
                switch (session.getType()) {
                    case DBConstans.COMMENT:
                    case DBConstans.LIKE:
                        if (!session.isInfoDelete) {
                            intent  = new Intent(context, ShowSingleInfo.class);
                            intent.putExtra(ShowSingleInfo.INFO_ID, session.getInfoId());
                            context.startActivity(intent);
                        }
                        break;
                    case DBConstans.SHARE:
                        intent = new Intent(context, ChannelActivity.class);
                        intent.putExtra(ChannelActivity.LOCATION_ID,session.getLocationId());
                        context.startActivity(intent);
                        break;
                }
            }else if (v.getTag(R.integer.view_click_session)!=null){
                ((ChatActivity)context).hideSoftInput();
            }
        }
    }


    /**
     * 播放对应的音频
     *
     * @param session
     * @param tv
     * @param audioPath
     */
    private void play(final Session session, final TextView tv, final String audioPath) {
        if (!TextUtils.isEmpty(audioPath) && new File(audioPath).exists()) {
            try {
                audioPlayer = new AudioPlayer();
                session.isPlaying = true;
                changeAudioDrawable(session, tv);
                audioPlayer.start(audioPath, new AudioPlayer.OnFinishedCallBack() {
                    @Override
                    public void onFinished(String path) {
                        session.isPlaying = false;
                        changeAudioDrawable(session, tv);
                    }
                });
            } catch (IOException | IllegalArgumentException e) {
                e.printStackTrace();
                session.isPlaying = false;
                audioPlayer.stop();
                changeAudioDrawable(session, tv);
            }
        }
    }

    /**
     * 根据音频是否播放，改变Drawable
     *
     * @param session
     * @param tv
     */
    private void changeAudioDrawable(Session session, TextView tv) {
        if (session.equals(tv.getTag(R.integer.audio_play_key_session))) {
            boolean isSelfSent = false;
            if (session.getFromUserId().equals(selfId)) {
                isSelfSent = true;
            }
            boolean isPlaying = session.isPlaying;
            if (isPlaying) {
                if (session.getType().equals(DBConstans.AUDIO)) {
                    if (isSelfSent) {
                        AnimationDrawable animationDrawable = (AnimationDrawable) context.getResources().getDrawable(R.drawable.anim_microphone_little);
                        tv.setCompoundDrawablesWithIntrinsicBounds(animationDrawable, null, null, null);
                        ((AnimationDrawable) (tv.getCompoundDrawables()[0])).start();
                    } else {
                        tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.anim_microphone_little_gray, 0, 0, 0);
                        ((AnimationDrawable) (tv.getCompoundDrawables()[0])).start();
                    }
                } else if (session.getType().equals(DBConstans.PIC_AUDIO)) {
                    if (isSelfSent) {
                        tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.anim_microphone_big, 0, 0, 0);
                        ((AnimationDrawable) (tv.getCompoundDrawables()[0])).start();
                    } else {
                        tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.anim_microphone_big_gray, 0, 0, 0);
                        ((AnimationDrawable) (tv.getCompoundDrawables()[0])).start();
                    }
                }
            } else {
                if (session.getType().equals(DBConstans.AUDIO)) {
                    if (isSelfSent) {
                        tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.microphone_little, 0, 0, 0);
                    } else {
                        tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.microphone_little_gray, 0, 0, 0);
                    }
                } else {
                    if (isSelfSent) {
                        tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.microphone_big, 0, 0, 0);
                    } else {
                        tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.microphone_big_gray, 0, 0, 0);
                    }
                }
            }
        }
    }

    @Override
    public boolean onLongClick(View v) {
        if (v.getTag(R.integer.view_long_click_session) != null) {
            Session session = (Session) v.getTag(R.integer.view_long_click_session);
            ((ChatActivity) context).showCopyOrDeleteDialog(session);
        }
        return false;
    }

    @Override
    public int getItemViewType(int position) {
        String type = sessionList.get(position).getType();
        String fromUserId = sessionList.get(position).getFromUserId();
        boolean isSelfSent = false;
        if (fromUserId.equals(selfId)) {
            isSelfSent = true;
        }
        if (!TextUtils.isEmpty(type)) {
            if (type.equals(DBConstans.TEXT) || type.equals(DBConstans.AUDIO)) {
                if (isSelfSent) {
                    return TEXT_RIGHT;
                } else {
                    return TEXT_LEFT;
                }
            }
            if (type.equals(DBConstans.PIC)) {
                if (isSelfSent) {
                    return PIC_RIGHT;
                } else {
                    return PIC_LEFT;
                }
            }
            if (type.equals(DBConstans.PIC_AUDIO)) {
                if (isSelfSent) {
                    return PIC_AUDIO_RIGHT;
                } else {
                    return PIC_AUDIO_LEFT;
                }
            }
            if (type.equals(DBConstans.COMMENT) || type.equals(DBConstans.LIKE) || type.equals(DBConstans.SHARE)) {
                if (isSelfSent) {
                    return COMMENT_RIGHT;
                } else {
                    return COMMENT_LEFT;
                }
            }
        }
        return super.getItemViewType(position);
    }

    @Override
    public int getViewTypeCount() {
        return 8;
    }

    public void changeList(List<Session> sessions) {
        if (sessionList.size() != sessions.size()) {
            this.sessionList = sessions;
        } else {
            this.sessionList = sessions;
        }
        notifyDataSetChanged();
    }

    public void onDestroy() {
        context = null;
        stopAudio();
        audioPlayer = null;
        sessionList = null;
    }

    class Comment extends BaseHolder<ChatCommentPresenter> implements IChatCommentView {
        @CustomFont(ConsTants.TYPE_FACE)
        @FindView(R.id.tv_chat_comment_text)
        public TextView tvCommentText;
        @FindView(R.id.iv_chat_comment_content_pic)
        public SimpleDraweeView ivContentPic;
        @CustomFont(ConsTants.TYPE_FACE)
        @FindView(R.id.tv_chat_comment_content_text)
        public TextView tvContentText;
        @FindView(R.id.iv_chat_comment_content_recommond_into)
        public ImageView ivContentRecommondInto;
        public Base base;
        private Session session;
        public Comment() {
            base = new Base();
        }

        @Override
        protected ChatCommentPresenter createP() {
            return new ChatCommentPresenter();
        }

        public void requestInfo(Long infoId) {
            presenter.requestInfo(infoId);
        }

        public void requestLocation(Long locationId) {
            presenter.requestLocation(locationId);
        }

        @Override
        public void setContentText(String text) {
            tvContentText.setText(text);
        }

        @Override
        public void setImageUri(Uri uri) {
            if (uri != null) ivContentPic.setImageURI(uri);
        }

        @Override
        public void setContentImgVisible(boolean visible) {
            if (visible) {
                ivContentPic.setVisibility(View.VISIBLE);
            } else {
                ivContentPic.setVisibility(View.GONE);
            }
        }

        @Override
        public void setIsInfoDelete(boolean b) {
            session.isInfoDelete = b;
        }

        public void setSession(Session session) {
            this.session = session;
        }
    }

    class PicAudio extends BaseHolder<ChatAudioPresenter> {
        @FindView(R.id.iv_chat_pic)
        public SimpleDraweeView ivPic;
        @CustomFont(ConsTants.TYPE_FACE)
        @FindView(R.id.tv_chat_text)
        public TextView tvText;
        public Base base;

        public PicAudio() {
            base = new Base();
        }

        @Override
        protected ChatAudioPresenter createP() {
            return new ChatAudioPresenter();
        }

        public void downAudio(Session session) {
            presenter.downAudio(session);
        }
    }

    class Pic {
        @CustomFont(ConsTants.TYPE_FACE)
        @FindView(R.id.iv_chat_pic)
        public SimpleDraweeView ivPic;
        public Base base;

        public Pic() {
            base = new Base();
        }
    }

    class Text extends BaseHolder<ChatAudioPresenter> {
        @CustomFont(ConsTants.TYPE_FACE)
        @FindView(R.id.tv_chat_text)
        public TextView tvText;
        public Base base;

        public Text() {
            base = new Base();
        }

        @Override
        protected ChatAudioPresenter createP() {
            return new ChatAudioPresenter();
        }

        public void downAudio(Session session) {
            presenter.downAudio(session);
        }
    }

    class Base {
        @CustomFont(ConsTants.TYPE_FACE)
        @FindView(R.id.tv_sendtime)
        public TextView tvSendTime;

        @FindView(R.id.sending_bar)
        public ProgressBar sendingBar;

        @FindView(R.id.iv_failed_status)
        public ImageView ivFailedStatus;

        @FindView(R.id.iv_chat_avater)
        public SimpleDraweeView ivAvater;
    }

}
